Cellen 2

Data visualisation — themes and multiple plots

Gavin Simpson

Aarhus University

2025-02-24

Introduction

In this section, we’ll look at

  • themes
  • placing multiple plots in a single plot

Data

In this video we’ll use the penguins data set from the palmerpenguins 📦

We’ll also make use of the GB bovine TB data set

library("palmerpenguins")
library("ggplot2")
library("dplyr")
library("readxl")

bovine <- read_xlsx("data/bovine-tb/gb-tb-stats.xlsx") |>
  mutate(date = as.Date(date), year = format(date, "%Y"),
    doy = as.numeric(format(date, "%j"))) |>
  rename(n_cases = n_not_otf)

penguin_labs <- labs(x = "Bill length (mm)", y = "Flipper length(mm)")

Themes

  • Theme Plots comprise a number of features that are not directly related to the data
    • grid lines
    • background
    • legend placement
    • typeface To adjust these features use the theme() function or a pre-set theme e.g. theme_bw()

Themes

The ggplot2 theme system allows control over the non-data elements of a plot

  • fonts / typeface
  • ticks & grid lines
  • panel strips
  • backgrounds
  • legends

In ggplot2, we create a plot by deciding how the data is displayed

The theme controls how it looks when you display it

Themes

Four main components to themes

  1. Theme elements specify the non-data elements you can control

    • plot.title, axis.ticks.x, legend.key.height
  2. Each element is associated with an element function

    • element_text() sets the font size, colour, & typeface of text elements
  3. The theme() function allows you to overrid the default theme elements

    • + theme(plot.title = element_text(colour = "red"))
  4. Complete themes set all of the theme elements to values designed to wokr together

    • theme_grey(), theme_bw(), theme_minimal(), …

Base plot

base <- penguins |>
  ggplot(aes(x = bill_length_mm, y = flipper_length_mm, colour = species)) +
  geom_point() +
  geom_smooth(method = "lm", colour = "grey50", linewidth = 2, se = FALSE)
base

Add some labels

labelled <- base +
  labs(x = "Bill length (mm)",
       y = "Flipper length (mm)",
       colour = "Species",
       title = "How big are penguins?") +
  scale_colour_brewer(type = "seq", palette = "Dark2")
labelled  

Style the plot with theme()

styled <- labelled +
  guides(colour = guide_legend(position = "inside")) +
  theme(plot.title = element_text(face = "bold", size = 18),
        legend.background = element_rect(fill = "white", linewidth = 4,
                                         colour = "white"),
        legend.justification = c(0,1),
        legend.position.inside = c(0,1),
        axis.ticks = element_line(colour = "grey70", linewidth = 0.2),
        panel.grid.major = element_line(colour = "grey70", linewidth = 0.2),
        panel.grid.minor = element_blank())
styled

Style the plot with theme()

Complete themes

ggplot2 📦 comes with many in-built themes & add-on packages provide many more

theme_grey() is the default theme

  • light grey background with white gridlines
  • the data are at the fore, grid lines allow for comparison
  • the grid lines are subtle, have little visual impact
  • grey background is similar in colour to blocks of text in long documents — graphics fit in with the text
  • grey background provides a continuous field of colour — the plot is perceived as a single entity

Add on packages: ggthemes 📦

In-built themes

There are seven additional in-built themes

  1. theme_bw()
  2. theme_line_draw()
  3. theme_light()
  4. theme_dark()
  5. theme_minimal()
  6. theme_classic()
  7. theme_void()

In-built themes I

In-built themes II

In-built themes III

Using a complete theme

Add the theme as a layer to the plot

labelled + theme_minimal()

Setting the theme

To set the theme permanently for the session use theme_set()

labelled
theme_set(theme_bw())
labelled

Modifying theme components

To modify an individual theme component you add + theme(...) to a plot:

plot + theme(element.name = element.function())

Four basic types of built-in elements

  1. text
  2. lines
  3. rectangles,
  4. blank

Modifying theme components

  • element_text() draws labels and headings — anything text

    • family, face, colour, size (pts), hjust, vjust, angle (deg), lineheight, margin
  • element_line() draws lines

    • colour, linewidth, linetype
  • element_rect() draws rectangles, used mostly for backgrounds on plot elements

    • fill, colour, linewidth, linetype
  • element_blank() draws nothing — use this if you don’t want an theme component to be drawn

Modifying theme components

df <- data.frame(x = 1:3, y = 1:3)
base <- ggplot(df, aes(x, y)) + geom_point() + ggtitle("This is a ggplot")

base + theme(plot.title = element_text(size = 16, face = "bold",
                                       colour = "red", hjust = 1))

Modifying theme components

base + theme(plot.title = element_text(margin = margin(t = 10, b = 20)))

Modifying theme components

base + theme(panel.grid.major = element_line(colour = "red", size = 2),
             panel.grid.minor = element_line(linetype = "dashed",
                                             colour = "blue"))

Modifying theme components

base + theme(plot.background = element_rect(colour = "red", fill = "grey80"))
base + theme(panel.background = element_rect(fill = "linen", colour = "red"))

Multiple plots

There are a number of ways to produce a figure with multiple separate panels

  • the patchwork package is now the one I use most
library("patchwork")

Multiple plots

patchwork works by taking multiple pre-prepared plots and arranging them on the device

Can set the number of columns and rows to spread the plots over and axes are automatically aligned

## plot 1
p1 <- base + theme(plot.title = element_text(margin = margin(t = 10, b = 20)))
## plot 2
p2 <- base + theme(panel.grid.major = element_line(colour = "red", size = 2),
                   panel.grid.minor = element_line(linetype = "dashed",
                                                   colour = "blue"))
## plot 3
p3 <- base + theme(plot.background = element_rect(colour = "red", fill = "grey80"))
## plot 4
p4 <- base + theme(panel.background = element_rect(fill = "linen", colour = "red"))

Multiple plots

Then arrange the plots using +, / and |

Grouping plots can be done with ( )

(p1 | p2) / (p3 | p4)

Multiple plots

Juxtapose plots using +

p1 <- penguins |>
  ggplot(aes(x = bill_length_mm, y = flipper_length_mm, colour = species)) +
  geom_point()
p2 <- penguins |>
  ggplot(aes(x = bill_length_mm, y = flipper_length_mm, colour = body_mass_g)) +
  geom_point()
p1 + p2

Multiple plots

Make more complex arrangements

p3 <- penguins |>
  ggplot(aes(x = bill_length_mm, y = flipper_length_mm, colour = sex)) +
  geom_point()
(p1 | p2) / p3

Multiple plots

Additional control through plot_layout()

p1 + p2 + p3 + plot_layout(ncol = 2, widths = c(2,1), heights = c(1,2))

Multiple plots

Even more control through a design

layout <- "
##BBBB
AACCCC
AACCCC
"
p1 + p2 + p3 + plot_layout(design = layout)

Multiple plots

Can gather the guides into one place

(p1 | p2) / p3 + plot_layout(guides = "collect")

Multiple plots; annotation

plot_annotation() is used to add annotations to the patchwork

patchwork <- (p1 + p2) / p3
patchwork + plot_annotation(
  title = 'The surprising truth about mtcars',
  subtitle = 'These 3 plots will reveal yet-untold secrets about our beloved data-set',
  caption = 'Disclaimer: None of these plots are insightful'
)

Multiple plots; annotation

Tags are for more formal layouts

patchwork + plot_annotation(tag_levels = c('A', '1'), tag_prefix = 'Fig. ',
                            tag_suffix = ':')